package org.erp.procurement.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.erp.common.constant.Constants;
import org.erp.common.enums.SysWhetherEnum;
import org.erp.common.page.PageQueryModel;
import org.erp.procurement.convert.PcOrderConvert;
import org.erp.procurement.entity.OrderProductDetails;
import org.erp.procurement.entity.PcOrder;
import org.erp.procurement.entity.ProcurementPayment;
import org.erp.procurement.entity.bo.OrderUpdateBo;
import org.erp.procurement.entity.bo.PcOrderAddBo;
import org.erp.procurement.entity.dto.PcOrderQueryDto;
import org.erp.procurement.entity.vo.PcOrderVo;
import org.erp.procurement.enums.OrderEventEnum;
import org.erp.procurement.enums.PaymentStatusEnum;
import org.erp.procurement.mapper.PcOrderMapper;
import org.erp.procurement.service.OrderProductDetailsService;
import org.erp.procurement.service.OrderStateMachineService;
import org.erp.procurement.service.PcOrderService;
import org.erp.procurement.service.ProcurementPaymentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author libin
 * @version 1.0
 * @description:
 * @date 2025/11/5 11:06
 **/
@Log4j2
@Service
@AllArgsConstructor
public class PcOrderServiceImpl extends ServiceImpl<PcOrderMapper, PcOrder> implements PcOrderService {

    private final PcOrderConvert pcOrderConvert;

    private final OrderProductDetailsService orderProductDetailsService;

    private final OrderStateMachineService orderStateMachineService;

    private final ProcurementPaymentService procurementPaymentService;

    @Override
    public PageQueryModel<PcOrderVo> pcPageList(PcOrderQueryDto pcOrderQueryDto) {
        Page<PcOrder> page = this.page(pcOrderQueryDto.buildPage()
                , new QueryWrapper<PcOrder>().lambda()
                        .like(StringUtils.isNotBlank(pcOrderQueryDto.getOrderNo()), PcOrder::getOrderNo, pcOrderQueryDto.getOrderNo())
                        .like(StringUtils.isNotBlank(pcOrderQueryDto.getSellName()), PcOrder::getSellName, pcOrderQueryDto.getSellName())
                        .eq(null != pcOrderQueryDto.getTenantId(), PcOrder::getTenantId, pcOrderQueryDto.getTenantId())
                        .eq(null != pcOrderQueryDto.getStatus(), PcOrder::getStatus, pcOrderQueryDto.getStatus())
                        .ge(null != pcOrderQueryDto.getStartTime(), PcOrder::getCreateTime, pcOrderQueryDto.getStartTime())
                        .le(null != pcOrderQueryDto.getEndTime(), PcOrder::getCreateTime, pcOrderQueryDto.getEndTime()));
        return PageQueryModel.of(page.getPages(), page.getRecords().stream()
                .map(pcOrderConvert::convertVo).toList());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void pcSave(PcOrderAddBo pcOrderAddBo) {
        PcOrder pcOrder = PcOrder.addBuild(pcOrderAddBo);
        //todo 获取租户id,name
        List<OrderProductDetails> orderProductDetailsList = orderProductDetailsService.buildOrderProductDetailsList(pcOrderAddBo.getOrderProductDetailsAddBoList(), pcOrder.getOrderNo());
        this.save(pcOrder);
        orderProductDetailsService.saveBatch(orderProductDetailsList);
        ProcurementPayment procurementPayment = new ProcurementPayment();
        procurementPayment.setPaymentNo(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
                + String.valueOf(Math.random()).substring(2, 6));
        procurementPayment.setOrderNo(pcOrder.getOrderNo());
        procurementPayment.setSellId(pcOrder.getSellId());
        procurementPayment.setTenantId(pcOrder.getTenantId());
        procurementPayment.setAmount(pcOrder.getRecycleAmount());
        procurementPayment.setChannel(1);
        procurementPayment.setStatus(PaymentStatusEnum.TO_BE_PAID.getCode());
        procurementPaymentService.save(procurementPayment);
        if (SysWhetherEnum.NO.getCode().equals(pcOrderAddBo.getIsSell())) {
            try {
                //todo 调用财务模块获取订单状态
                if (Constants.SUCCESS.equals(200)) {
                    procurementPayment.setStatus(PaymentStatusEnum.SUCCESS.getCode());
                } else {
                    procurementPayment.setStatus(PaymentStatusEnum.FAILED.getCode());
                    procurementPayment.setFailedMessage("业务异常");
                }
            } catch (Exception e) {
                procurementPayment.setStatus(PaymentStatusEnum.FAILED.getCode());
                procurementPayment.setFailedMessage("系统调用异常");
            }
            procurementPaymentService.updateById(procurementPayment);
            if (PaymentStatusEnum.SUCCESS.getCode().equals(procurementPayment.getStatus())) {
                boolean process = orderStateMachineService.process(pcOrder.getOrderNo(), OrderEventEnum.FINISH);
                if (!process) {
                    throw new IllegalStateException("更新状态失败,请稍后再试");
                }
            }
        }
    }

    @Override
    public void updatePurchaseQuantity(OrderUpdateBo orderUpdateBo) {
        PcOrder pcOrder = this.getOne(new QueryWrapper<PcOrder>().lambda()
                .eq(PcOrder::getOrderNo, orderUpdateBo.getOrderNo()));
        pcOrder.setPurchaseQuantity(orderUpdateBo.getPurchaseQuantity());
        this.updateById(pcOrder);
    }
}
